﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.ExtensibleStorage;

namespace YJKStairs.CommonUnit
{
	public class ElementXDataManager
	{
		private static Schema CreateSimpleSchema(string sSchemaName, Type type)
		{
			SchemaBuilder schemaBuilder = new SchemaBuilder(ElementXDataManager.m_Guid);
			schemaBuilder.SetReadAccessLevel((AccessLevel)1);
			schemaBuilder.SetSchemaName(sSchemaName);
			schemaBuilder.AddSimpleField(sSchemaName, type);
			return schemaBuilder.Finish();
		}

		private static Schema CreateArraySchema(string sSchemaName, Type type)
		{
			SchemaBuilder schemaBuilder = new SchemaBuilder(ElementXDataManager.m_Guid);
			schemaBuilder.SetReadAccessLevel((AccessLevel)1);
			schemaBuilder.SetSchemaName(sSchemaName);
			schemaBuilder.AddArrayField(sSchemaName, type);
			return schemaBuilder.Finish();
		}

		private static Schema CreateArraySchemaArr(string sSchemaName, List<string> arFieldName, List<Type> arType)
		{
			Schema result = null;
			if (string.IsNullOrEmpty(sSchemaName))
			{
				return result;
			}
			SchemaBuilder schemaBuilder = new SchemaBuilder(ElementXDataManager.m_Guid);
			schemaBuilder.SetSchemaName(sSchemaName);
			schemaBuilder.SetReadAccessLevel((AccessLevel)1);
			if (arFieldName.Count == arType.Count)
			{
				int num = 0;
				foreach (string text in arFieldName)
				{
					Type type = arType[num++];
					FieldBuilder fieldBuilder = schemaBuilder.AddArrayField(text, type);
					if (fieldBuilder.NeedsUnits())
					{
						fieldBuilder.SetUnitType(0);
					}
				}
				result = schemaBuilder.Finish();
			}
			return result;
		}

		private static void WriteElementIdArray(Element element, string sFieldName, List<ElementId> arId)
		{
			Schema schema = null;
			if (ElementXDataManager.HasSchema(element, out schema))
			{
				if (ElementXDataManager.m_StairsEnt == null)
				{
					ElementXDataManager.m_StairsEnt = new Entity(schema);
				}
				Field field = schema.GetField(sFieldName);
				ElementXDataManager.m_StairsEnt.Set<IList<ElementId>>(field, arId);
			}
		}

		private static void WriteDoubleArray(Element element, string sFieldName, List<double> arDouble)
		{
			Schema schema = null;
			if (ElementXDataManager.HasSchema(element, out schema))
			{
				if (ElementXDataManager.m_StairsEnt == null)
				{
					ElementXDataManager.m_StairsEnt = new Entity(schema);
				}
				Field field = schema.GetField(sFieldName);
                ElementXDataManager.m_StairsEnt.Set<IList<double>>(field, arDouble, (DisplayUnitType)6);
			}
		}

		private static void WriteStringArray(Element element, string sFieldName, List<string> arString)
		{
			Schema schema = null;
			if (ElementXDataManager.HasSchema(element, out schema))
			{
				if (ElementXDataManager.m_StairsEnt == null)
				{
					ElementXDataManager.m_StairsEnt = new Entity(schema);
				}
				Field field = schema.GetField(sFieldName);
				ElementXDataManager.m_StairsEnt.Set<IList<string>>(field, arString);
			}
		}

		private static void CommitXData(Element element)
		{
			if (ElementXDataManager.m_StairsEnt != null)
			{
				element.SetEntity(ElementXDataManager.m_StairsEnt);
				ElementXDataManager.m_StairsEnt = null;
			}
		}

		public static bool ElementHasGuid(Element element, Guid guid)
		{
			bool result = false;
			if (element != null)
			{
				result = element.GetEntitySchemaGuids().Contains(guid);
			}
			return result;
		}

		private static List<ElementId> ReadElementIdArray(Element element, string sFieldName)
		{
			List<ElementId> result = new List<ElementId>();
			if (!ElementXDataManager.ElementHasGuid(element, ElementXDataManager.m_Guid))
			{
				return result;
			}
			Schema schema = Schema.Lookup(ElementXDataManager.m_Guid);
			if (schema != null)
			{
				Entity entity = element.GetEntity(schema);
				if (entity != null)
				{
					Field field = schema.GetField(sFieldName);
					if (field != null)
					{
						result = entity.Get<IList<ElementId>>(field).ToList<ElementId>();
					}
				}
			}
			return result;
		}

		private static List<double> ReadDoubleArray(Element element, string sFieldName)
		{
			List<double> result = new List<double>();
			Schema schema = Schema.Lookup(ElementXDataManager.m_Guid);
			if (schema != null)
			{
				Entity entity = element.GetEntity(schema);
				if (entity != null)
				{
					Field field = schema.GetField(sFieldName);
					if (field != null)
					{
                        result = entity.Get<IList<double>>(field, (DisplayUnitType)6).ToList<double>();
					}
				}
			}
			return result;
		}

		private static List<string> ReadStringArray(Element element, string sFieldName)
		{
			List<string> result = new List<string>();
			if (!ElementXDataManager.ElementHasGuid(element, ElementXDataManager.m_Guid))
			{
				return result;
			}
			Schema schema = Schema.Lookup(ElementXDataManager.m_Guid);
			if (schema != null)
			{
				Entity entity = element.GetEntity(schema);
				if (entity != null)
				{
					Field field = schema.GetField(sFieldName);
					if (field != null)
					{
						result = entity.Get<IList<string>>(field).ToList<string>();
					}
				}
			}
			return result;
		}

		private static bool HasSchema(Element element, out Schema schema)
		{
			bool result = false;
			Schema schema2 = Schema.Lookup(ElementXDataManager.m_Guid);
			if (schema2 == null)
			{
				schema = schema2;
				return result;
			}
			schema = schema2;
			return true;
		}

		public static void CreateStairsXDataSchema(Stairs stairs, string sSchemaName, List<string> arFieldName, List<Type> arFieldType)
		{
			Schema schema = null;
			if (!ElementXDataManager.HasSchema(stairs, out schema))
			{
				ElementXDataManager.CreateArraySchemaArr(sSchemaName, arFieldName, arFieldType);
			}
		}

		public static void WriteStairsBeamXData(Stairs stairs, string sFieldName, List<ElementId> arBeamId)
		{
			ElementXDataManager.WriteElementIdArray(stairs, sFieldName, arBeamId);
		}

		public static void WriteStairsLandWidthXData(Stairs stairs, string sFieldName, List<string> arLandWidth)
		{
			ElementXDataManager.WriteStringArray(stairs, sFieldName, arLandWidth);
		}

		public static List<ElementId> ReadStairsBeamXData(Stairs stairs, string sFieldName)
		{
			return ElementXDataManager.ReadElementIdArray(stairs, sFieldName);
		}

		public static List<double> ReadStairsLandXData(Stairs stairs, string sFieldName)
		{
			List<double> list = new List<double>();
			foreach (string s in ElementXDataManager.ReadStringArray(stairs, sFieldName))
			{
				double item = 0.0;
				if (double.TryParse(s, out item))
				{
					list.Add(item);
				}
			}
			return list;
		}

		public static void CommitStairsXData(Stairs stairs)
		{
			ElementXDataManager.CommitXData(stairs);
		}

		public static bool StairsHasXDataGuid(Stairs stairs)
		{
			bool result = false;
			if (stairs != null && ElementXDataManager.ElementHasGuid(stairs, ElementXDataManager.m_Guid) && ElementXDataManager.ReadStairsBeamXData(stairs, ElementXDataManager.m_sStairsBeam).Count > 0)
			{
				result = true;
			}
			return result;
		}

		public static void SetElementXData(Element element, string sSchemaName, int Value)
		{
			Entity entity = null;
			Field field = null;
			if (ElementXDataManager.HasSchemaName(element, sSchemaName, out entity, out field))
			{
				entity.Set<int>(field, Value);
				element.SetEntity(entity);
				return;
			}
			Schema schema = null;
			if (ElementXDataManager.HasSchema(element, out schema))
			{
				Entity entity2 = new Entity(schema);
				Field field2 = schema.GetField(sSchemaName);
				entity2.Set<int>(field2, Value);
				element.SetEntity(entity2);
				return;
			}
			schema = ElementXDataManager.CreateSimpleSchema(sSchemaName, typeof(ElementId));
			Entity entity3 = new Entity(schema);
			Field field3 = schema.GetField(sSchemaName);
			entity3.Set<int>(field3, Value);
			element.SetEntity(entity3);
		}

		public static void SetElementXData(Element element, string sSchemaName, ElementId Value)
		{
			Entity entity = null;
			Field field = null;
			if (ElementXDataManager.HasSchemaName(element, sSchemaName, out entity, out field))
			{
				entity.Set<ElementId>(field, Value);
				element.SetEntity(entity);
				return;
			}
			Schema schema = null;
			if (ElementXDataManager.HasSchema(element, out schema))
			{
				Entity entity2 = new Entity(schema);
				Field field2 = schema.GetField(sSchemaName);
				entity2.Set<ElementId>(field2, Value);
				element.SetEntity(entity2);
				return;
			}
			schema = ElementXDataManager.CreateSimpleSchema(sSchemaName, typeof(ElementId));
			Entity entity3 = new Entity(schema);
			Field field3 = schema.GetField(sSchemaName);
			entity3.Set<ElementId>(field3, Value);
			element.SetEntity(entity3);
		}

		public static int GetElementXData(Element element, string sSchemaName)
		{
			Schema schema = Schema.Lookup(ElementXDataManager.m_Guid);
			Entity entity = element.GetEntity(schema);
			int result = -1;
			if (entity != null)
			{
				result = entity.Get<int>(schema.GetField(sSchemaName));
			}
			return result;
		}

		public static bool HasSchemaName(Element element, string sSchemaName)
		{
			bool flag = false;
			Schema schema = Schema.Lookup(ElementXDataManager.m_Guid);
			if (schema == null)
			{
				return flag;
			}
			if (element.GetEntity(schema) == null)
			{
				return flag;
			}
			return schema.GetField(sSchemaName) != null || flag;
		}

		public static bool HasSchemaName(Element element, string sSchemaName, out Entity ent, out Field filed)
		{
			bool result = false;
			Entity entity = null;
			Field field = null;
			Schema schema = Schema.Lookup(ElementXDataManager.m_Guid);
			if (schema == null)
			{
				ent = entity;
				filed = field;
				return result;
			}
			entity = element.GetEntity(schema);
			if (entity == null)
			{
				ent = entity;
				filed = field;
				return result;
			}
			field = schema.GetField(sSchemaName);
			if (field == null)
			{
				ent = entity;
				filed = field;
				return result;
			}
			ent = entity;
			filed = field;
			return true;
		}

		public static void DeleteSchmaFiled(Element element, string sSchemaName)
		{
			Transaction transaction = new Transaction(element.Document, "delete Xdata");
			transaction.Start();
			Schema schema = Schema.Lookup(ElementXDataManager.m_Guid);
			if (schema == null)
			{
				return;
			}
			Entity entity = element.GetEntity(schema);
			if (entity == null)
			{
				return;
			}
			Field field = schema.GetField(sSchemaName);
			if (field == null)
			{
				return;
			}
			entity.Clear(field);
			transaction.Commit();
		}

		public static void DeleteSchma(Element element)
		{
			Schema schema = Schema.Lookup(ElementXDataManager.m_Guid);
			if (schema != null)
			{
				Transaction transaction = new Transaction(element.Document, "delete Schma");
				transaction.Start();
				element.DeleteEntity(schema);
				transaction.Commit();
			}
		}

		private static Guid m_Guid = new Guid("5C362734-8E4B-42EB-AB71-C9B49C114F0A");

		public static string m_sStairsBeam = "BeamIds";

		public static string m_sStairsLand = "LandWidth";

		public static Entity m_StairsEnt = null;
	}
}
